/************************************
 * Package: RGcpp					*
 * Authors: Rui Eduardo Gouveia Gil	*
 * Date: 2010						*
 ************************************/
#ifndef __RGCPP_HTTPSESSION_H__
#define __RGCPP_HTTPSESSION_H__

#include <string>
#include <fstream>
#include <iostream>
#include <curl/curl.h>
#include <curl/easy.h>
#include <curl/types.h>
#include <boost/thread.hpp>

#include "rgcpp/structs/Types.h"
#include "rgcpp/exceptions/RuntimeException.h"

namespace rgcpp
{

class HTTPSession
{
	private:
		static bool globalInit;
		static boost::mutex globalMut;

		bool debug;
		CURL* curl;
		bool caAutoAllow;
		std::string caPath;
		unsigned int timeout;
		std::string cookiesPath;
		Types<std::string,std::string> httpAuthData;

	public:
		HTTPSession();
		~HTTPSession();

		void setDebugMode(bool debug);
		bool isDebugMode();

		void setTimeout(unsigned int timeout);
		unsigned int getTimeout();

		void setHttpAuth(const std::string& user, const std::string& pass);
		Types<std::string,std::string> getHttpAuth();

		void setCookiesPath(const std::string& cookiesPath);
		std::string getCookiesPath();

		void setCertificateAuthorityPath(const std::string& caPath);
		std::string getCertificateAuthorityPath();

		void setCertificateAuthorityAutomaticAllow(bool caAutoAllow);
		bool isCertificateAuthorityAutomaticAllow();

		std::string performGet(const std::string& uri);
		void performGetToNull(const std::string& uri);
		void performGetToFile(const std::string& uri, const std::string& filePath);

		void performPut(const std::string& uri, const std::string& filePath);

		std::string performPost(const std::string& uri, const std::string& data);
		std::string performPostFromFile(const std::string& uri, const std::string& filePath);
		void performPostFromFileToFile(const std::string& uri, const std::string& srcFilePath, const std::string& dstFilePath);

	private:
		static void initGlobalCurl();

		static size_t requestFileCallback(void* ptr, size_t size, size_t nmemb, void* stream);
		static size_t requestStreamCallback(void* ptr, size_t size, size_t nmemb, void* stream);

		static size_t responseFileCallback(void* ptr, size_t size, size_t nmemb, void* stream);
		static size_t responseStreamCallback(void* ptr, size_t size, size_t nmemb, void* stream);
};

}

#endif
